/**
 * Pubsub events:
 *
 *  set-theme(theme)         设置主题
 *  toggle-theme             切换主题
 *
 *  sidebar-folder-open      文件夹侧边栏打开
 *  sidebar-folder-close     文件夹侧边栏关闭
 *  sidebar-folder-toggle    文件夹侧边栏切换
 *
 *  sidebar-directory-open   目录侧边栏打开
 *  sidebar-directory-close  目录侧边栏关闭
 *  sidebar-directory-toggle 目录侧边栏切换
 *
 *  sidebar-history-open     历史侧边栏打开
 *  sidebar-history-close    历史侧边栏关闭
 *  sidebar-history-toggle   历史侧边栏切换
 *
 *  page-start-open          打开起始页面
 *  page-setting-open        打开设置页面
 *
 *  selected-file(path)      从文件选择器中选择了一个文件
 *  selected-folder(path)    从文件选择器中选择了一个文件夹
 *  selected-folder-listed(tree)   从文件夹中列出了文件结构
 *  file-open                打开文件
 *  folder-open              打开文件夹
 *
 *  file-opened(fileInfo)    打开了文件
 *  files-all-closed         所有文件全部关闭
 *  folder-opened()          打开了文件夹
 *  article-tab-show         文章标签切换
 *
 *  re-render-current-files   重新渲染当前打开的文件
 *
 *  open-file-from-history   从历史记录中打开了文件
 *  open-file-from-folder    从文件夹列表中打开了文件
 *
 *  article-rendered(fileSha1)   文章渲染完成
 *
 *  clear-history            清空历史记录完成
 *
 *  custom-css-changed       自定义 CSS 更新了
 *
 *  article-anchor-change(id)文章锚点更换
 *  article-to-anchor(id)    文章滚动到指定锚点
 *
 *  app-reload               重载应用（Ctrl + Shift + R）
 *
 * 主进程发送来的事件：
 *
 *  before-close             应用关闭的事件，接受到该事件后，保存所有数据
 *  selected-file            在选择文件对话框中选择一个文件后，接受到该事件
 *  selected-folder          在选择文件夹对话框中选择一个文件夹后，接受到该事件
 *  shartcut-pressed(name)   按下快捷键：显示文件记录列表
 *
 * 发送给主进程的事件：
 *
 *  open-file-dialog         打开文件对话框
 *  open-folder-dialog       打开文件夹对话框
 *  before-close-complete    完成应用关闭前的保存操作
 *
 */

String.prototype.replaceAll  = function(s1,s2) {
  return this.replace(new RegExp(s1,"gm"),s2);
};

window.$$ = mdui.JQ;
window.$$body = $$('body');

const electron = require('electron');
const {ipcRenderer} = electron;
const fs = require('fs');
const path = require('path');

import Pubsub from '../helper/Pubsub.js';
import State from '../helper/State.js';
import DirTree from '../helper/DirTree.js';
import Activitybar from '../component/activitybar/index.js';
import Sidebar from '../component/sidebar/index.js';
import SidebarHistory from '../component/sidebar-history/index.js';
import SidebarDirectory from '../component/sidebar-directory/index.js';
import SidebarFolder from '../component/sidebar-folder/index.js';
import Page from '../component/page/index.js';
import PageSetting from '../component/setting/index.js';
import PageStart from '../component/start/index.js';

/**
 * 关闭之前保存所有状态
 */
ipcRenderer.on('before-close', (e) => {
  State.save();

  ipcRenderer.send('before-close-complete');
});

/**
 * 初始化页面
 */
new Activitybar($$('#activitybar'));
new Sidebar({
  folder: $$('#sidebar-folder'),
  directory: $$('#sidebar-directory'),
  history: $$('#sidebar-history')
});
new Page({
  tab: $$('#tab'),
  start: $$('#start'),
  article: $$('#article'),
  setting: $$('#setting')
});
new PageStart($$('#start'));
new PageSetting($$('#setting'));
new SidebarHistory($$('#sidebar-history'));
new SidebarDirectory($$('#sidebar-directory'));
new SidebarFolder($$('#sidebar-folder'));

/**
 * 在外部浏览器中打开链接
 */
$$(document).on('click', 'a', function(e) {
  e.preventDefault();

  const $a = $$(this);
  const href = $a.attr('href');

  if (!href) {
    return;
  }

  if (href.startsWith('http://') || href.startsWith('https://')) {
    electron.shell.openExternal(href);
  }
});

/**
 * 监听快捷键
 */
ipcRenderer.on('shartcut-pressed', (e, name) => {
  switch(name) {
    case 'open-file':
      Pubsub.emit('file-open');
      break;
    case 'open-folder':
      Pubsub.emit('folder-open');
      break;
    case 'next-tab':

      break;
    case 'prev-tab':

      break;
    case 'page-start':
      Pubsub.emit('page-start-open');
      break;
    case 'sidebar-folder':
      Pubsub.emit('sidebar-folder-toggle');
      break;
    case 'sidebar-directory':
      Pubsub.emit('sidebar-directory-toggle');
      break;
    case 'sidebar-history':
      Pubsub.emit('sidebar-history-toggle');
      break;
    case 'toggle-theme':
      Pubsub.emit('toggle-theme');
      break;
    case 'page-setting':
      Pubsub.emit('page-setting-open');
      break;
    default:
      break;
  }
});

/**
 * 监听 app-reload，刷新页面
 */
Pubsub.subscribe('app-reload', () => {
  window.location.reload();
});

/**
 * 监听打开文件、打开文件夹操作，向主进程发送事件
 */
Pubsub.subscribe('file-open', () => {
  ipcRenderer.send('open-file-dialog');
});

Pubsub.subscribe('folder-open', () => {
  ipcRenderer.send('open-folder-dialog');
});

/**
 * 主进程中完成打开文件、文件夹操作的事件
 */
ipcRenderer.on('selected-file', (event, filePaths) => {
  const filePath = filePaths[0];
  Pubsub.emit('selected-file', filePath);
});

ipcRenderer.on('selected-folder', function(event, path) {
  const folderPath = path[0];
  Pubsub.emit('selected-folder', folderPath);
});

/**
 * 选择一个文件后，读取文件
 */
Pubsub.subscribe('selected-file', (filePath) => {
  // 判断文件扩展名
  if (State.getConfig('markdownExtensions').indexOf(path.extname(filePath).slice(1)) < 0) {
    mdui.snackbar({
      message: '不支持该类型的文件',
      position: 'left-bottom'
    });

    return;
  }

  // 获取文件信息
  fs.stat(filePath, function(err, stats) {
    if (err) {
      mdui.alert(err, '出错了');
      return;
    }

    let fileInfo = {
      filePath: filePath,                 // 文件路径
      fileName: path.basename(filePath)  // 文件名
    };

    State.addHistory(fileInfo);

    // 发送事件
    Pubsub.emit('file-opened', fileInfo);

    // 打开文件目录
    Pubsub.emit('sidebar-directory-open');
  });
});

/**
 * 选择一个文件夹后，读取文件夹结构
 */
Pubsub.subscribe('selected-folder', (folderPath) => {
  let tree = DirTree(folderPath, State.getConfig('markdownExtensions'));
  Pubsub.emit('selected-folder-listed', tree);

  // 打开文件夹侧边栏
  Pubsub.emit('sidebar-folder-open');
});

/**
 * 拖拽打开文件、文件夹
 */
$$(document).on('dragover', (ev) => {
  $$body.addClass('drag-ondrag');
  return false;
});

$$('#drag-notice').on('dragleave', (ev) => {
  $$body.removeClass('drag-ondrag');
  return false;
});

$$(document).on('drop', (ev) => {
  $$body.removeClass('drag-ondrag');

  let files = ev.dataTransfer.files;
  if (!files.length) {
    return;
  }

  let filePath = files[0].path;

  // 判断是文件还是文件夹
  fs.stat(filePath, function(err, stats) {
    if (stats.isFile()) {
      Pubsub.emit('selected-file', filePath);
    }

    if (stats.isDirectory()) {
      Pubsub.emit('selected-folder', filePath);
    }
  });

  return false;
});

/**
 * 注入自定义 CSS 到页面 head 部分
 */
function injectCSS() {
  let systemFontEN = State.getConfig('systemFontEN');
  let systemFontZH = State.getConfig('systemFontZH');
  let markdownCSS = State.getConfig('markdownCSS');
  let markdownLightCSS = State.getConfig('markdownLightCSS');
  let highlightDarkCSS = State.getConfig('highlightDarkCSS');
  let highlightLightCSS = State.getConfig('highlightLightCSS');
  let systemFontCSS = '';

  if (systemFontEN || systemFontZH) {
    systemFontCSS =
      systemFontEN +
      ((systemFontEN && systemFontZH) ? ',' : '') +
        systemFontZH;

    systemFontCSS = `html, body { font-family: ${systemFontCSS} !important }`;
  }
  markdownLightCSS = markdownLightCSS.replaceAll('.markdown-body', '.mdui-theme-layout-light .markdown-body');
  highlightDarkCSS = highlightDarkCSS.replaceAll('.hljs', '.mdui-theme-layout-dark .hljs');
  highlightLightCSS = highlightLightCSS.replaceAll('.hljs', '.mdui-theme-layout-light .hljs');

  let CSS = `<style class="head-custom-css">${systemFontCSS + markdownCSS + markdownLightCSS + highlightDarkCSS + highlightLightCSS}</style>`;

  $$('head .head-custom-css').remove();

  $$('head').append(CSS);
}

injectCSS();
Pubsub.subscribe('custom-css-changed', injectCSS);


// ==================================================
// =================== 启动后的初始化 ==================
// ==================================================

/**
 * 设置主题
 */
{
  let theme = State.getConfig('theme');
  Pubsub.emit('set-theme', theme);
}

/**
 * 打开起始页
 */
Pubsub.emit('page-start-open');